package repositorio;

import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import MyServer.IDirectorio;
import MyServer.IDirectorioPOA;
import MyServer.IRepositorio;

public class Directorio extends IDirectorioPOA {

	private List<String> nombresRepositorios;

	private static IDirectorio directorio;

	private org.omg.CORBA.Object refIDirectorio;

	private Directorio(String[] args, Properties prop) {
		this.nombresRepositorios = new LinkedList<String>();

		this.refIDirectorio = RepositorioUtilidades
				.registrarDirectorioServicioNombres(args, prop, this);

		Directorio.directorio = RepositorioUtilidades
				.obtenerReferenciaDirectorio(args, prop);
	}

	public static IDirectorio getInstance(String[] args, Properties props) {

		if (Directorio.directorio == null) {
			Directorio.directorio = RepositorioUtilidades
					.obtenerReferenciaDirectorio(args, props);
			if (Directorio.directorio == null)
				new Directorio(args, props);
			
			try{
				Directorio.directorio._toString();
				}
			catch(Exception e){
				
				new Directorio(args, props);
				System.out.println("REINICIANDO\n");
			}
			
		}

		return Directorio.directorio;
	}
	
	public org.omg.CORBA.Object getRefIDirectorio() {
		return this.refIDirectorio;
	}

	public String[] listarPosiblesRepositoriosPadre(IRepositorio repositorio) {

		String[] nombresAConectar;
		if (repositorio.esRaiz()) {
			// Obtengo los nombres de mis repositorios subordinados.
			String[] misSubordinados = repositorio.getNombresSubordinados();

			// Lista almacena todos los nombres de los repositorios registrados
			// en el DNS.
			Set<String> nombresRegistrados = new HashSet<String>();
			for (String nombre : this.nombresRepositorios) {
					nombresRegistrados.add(nombre);
			}

			for (int i = 0; i < misSubordinados.length; i++)
				nombresRegistrados.remove(misSubordinados[i]);

			// Arreglar chorrada
			nombresAConectar = new String[nombresRegistrados.size()];
			int i = 0;
			for (String nombre : nombresRegistrados) {
				nombresAConectar[i] = nombre;
				i++;
			}
		}
		else
			nombresAConectar = new String[0];

		return nombresAConectar;
	}

	@SuppressWarnings("unchecked")
	public boolean addNombreRepositorio(String nombreRepositorio) {

		boolean add = true;
		Iterator itNombresRepositorios = this.nombresRepositorios.iterator();
		String nombresUnRepositorio;
		boolean enc = false;

		while (itNombresRepositorios.hasNext() && !enc) {

			// Obtenemos la lista de nombres para el repositorio
			nombresUnRepositorio = (String)itNombresRepositorios.next();

			if (nombresUnRepositorio.equals(nombreRepositorio))
				enc = true;
		}
			
		if(!enc)
			this.nombresRepositorios.add(nombreRepositorio);
		
		return add;
	}

	@SuppressWarnings("unchecked")
	public boolean removeNombreRepositorio(String nombreRepositorio) {

		Iterator itNombresRepositorios = this.nombresRepositorios.iterator();
		String nombresUnRepositorio;
		boolean enc = false;

		while (itNombresRepositorios.hasNext() && !enc) {

			// Obtenemos la lista de nombres para el repositorio
			nombresUnRepositorio = (String) itNombresRepositorios.next();

			if (nombresUnRepositorio.equals(nombreRepositorio)){
				enc = true;
				itNombresRepositorios.remove();
			}
		}
		
		return enc;
	}

	public String[] listarRepositorioConectados() {
		String[] nombresR = new String[this.nombresRepositorios.size()];
		int i = 0;

		for (String nombre : this.nombresRepositorios) {
			nombresR[i] = nombre;
			i++;
		}

		return nombresR;
	}

	public String _toString() {

		String s = "Repositorios registrados en el DNS:\n";
		for (String nombre : this.nombresRepositorios)
			s += nombre+"\n";

		return s;
	}

	public int numeroRepositorioConectados() {

		return this.nombresRepositorios.size();
	}
}
